package ioc

import (
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
	etcdv3 "go.etcd.io/etcd/client/v3"
	"go.etcd.io/etcd/client/v3/naming/resolver"
	"go.uber.org/zap"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	intrv1 "jk-time/webook/api/proto/gen/intr/v1"
	"jk-time/webook/internal/client"
	"jk-time/webook/internal/service"
)

func InitIntrClient(svc service.InteractiveService) client.InteractiveSerivceClient {
	type Config struct {
		Addr      string `yaml:"addr"`
		Secure    bool   `yaml:"secure"`
		Threshold int32  `yaml:"threshold"`
	}
	var config Config
	err := viper.UnmarshalKey("grpc.client.intr", &config)
	if err != nil {
		panic(err)
	}

	var opts []grpc.DialOption
	if !config.Secure {
		opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
	}
	cc, err := grpc.Dial(config.Addr, opts...)
	if err != nil {
		panic(err)
	}

	remote := intrv1.NewInteractiveSerivceClient(cc)
	local := client.NewLocalInteractiveServiceAdapter(svc)
	res := client.NewInteractiveClient(remote, local, config.Threshold)

	viper.WatchConfig()
	viper.OnConfigChange(func(in fsnotify.Event) {
		zap.L().Debug("", zap.String("filename", in.Name), zap.String("op", in.Op.String()))
		var config Config
		err := viper.UnmarshalKey("grpc.client.intr", &config)
		if err != nil {
			panic(err)
		}
		res.UpdateThreshold(config.Threshold)
	})
	return res
}
func InitIntrClientV1(svc service.InteractiveService) client.InteractiveSerivceClient {
	type Config struct {
		Port      string `yaml:"port"`
		Secure    bool   `yaml:"secure"`
		Threshold int32  `yaml:"threshold"`
		Name      string `yaml:"name"`
	}
	var config Config
	err := viper.UnmarshalKey("grpc.client.intr", &config)
	addr := viper.GetString("etcd.addr")
	if err != nil {
		panic(err)
	}

	cli, err := etcdv3.NewFromURL(addr)
	if err != nil {
		panic(err)
	}
	etcdResolver, err := resolver.NewBuilder(cli)
	if err != nil {
		panic(err)
	}

	var opts []grpc.DialOption
	opts = append(opts, grpc.WithResolvers(etcdResolver))
	if !config.Secure {
		opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
	}
	cc, err := grpc.Dial("etcd:///service/"+config.Name, opts...)
	if err != nil {
		panic(err)
	}

	remote := intrv1.NewInteractiveSerivceClient(cc)
	local := client.NewLocalInteractiveServiceAdapter(svc)
	res := client.NewInteractiveClient(remote, local, config.Threshold)

	viper.WatchConfig()
	viper.OnConfigChange(func(in fsnotify.Event) {
		zap.L().Debug("", zap.String("filename", in.Name), zap.String("op", in.Op.String()))
		var config Config
		err := viper.UnmarshalKey("grpc.client.intr", &config)
		if err != nil {
			panic(err)
		}
		res.UpdateThreshold(config.Threshold)
	})
	return res
}
